/**
 * Projet de LIF12 : messagerie instantanée.
 * Partie serveur.
 *
 * @file server/main.c
 * @author Elsa FLECHON elsa.flechon@etu.univ-lyon1.fr
 * @author Emmanuel GAUDE emmanuel.gaude@etu.univ-lyon1.fr
 * @author Grégoire LEMASSON gregoire.lemasson@etu.univ-lyon1.fr
 * @since 2009/03/10
 * @version 2009/03/11
 */

/* -- Inclusion des en-têtes. ----------------------------------------------- */
#include <stdio.h> /* printf(), fprintf(), fflush(), stderr, stdout, perror() */
#include <stdlib.h> /* exit(), EXIT_SUCCESS, EXIT_FAILURE */
#include <unistd.h> /* close() */
#include <string.h> /* memset() */
#include <errno.h> /* errno */
#include <sys/types.h> /* socket(), bind(), listen(), socklen_t, size_t */
#include <sys/socket.h> /* socket(), bind(), listen(), AF_INET, SOCK_STREAM,
                           INADDR_ANY */
#include <arpa/inet.h> /* htons(), htonl() */


/* -- Définition des constantes. -------------------------------------------- */
#define SRV_PORT 26387 /**< Numéro de port du serveur. */
#define MAX_CONNECTIONS 16 /**< Nombre max de connexions. */

/* -- Point d'entrée du programme. ------------------------------------------ */
int main() {
  /* -- Variables locales. -------------------------------------------------- */
  int s = 0, t = 0; /**< Sockets. */
  struct sockaddr_in sa; /**< Adressage de la socket. */
  struct sockaddr saCli; /**< Adresse client. */
  socklen_t saCliLen; /**< Longueur adresse client. */

  /* -- Présentation du programme. ------------------------------------------ */
  printf("\033[1m -- Projet LIF12 : Messagerie instantanée --\n");
  printf(" -- Groupe 2 : FLECHON - GAUDE - LEMASSON --\n");
  printf(" -- Exécutable serveur (2009/03/11)       --\033[0m\n\n");

  printf("LOG D'EXÉCUTION :\n");

  /* -- Création de la socket. ---------------------------------------------- */
  printf(" - Création de la socket... ");
  fflush(stdout);
  if((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    perror("Erreur à la création de la socket ");
    exit(EXIT_FAILURE);
  }
  printf("OK\n");

  /* -- Attachement de la socket. ------------------------------------------- */
  printf(" - Attachement de la socket... ");
  fflush(stdout);
  memset(&sa, 0, sizeof(sa));
  sa.sin_family = AF_INET;
  sa.sin_port=htons(SRV_PORT);
  sa.sin_addr.s_addr=htonl(INADDR_ANY);
  if(bind(s, (const struct sockaddr*) &sa, sizeof(sa)) == -1) {
    perror("Erreur à l'attachement de la socket ");
    exit(EXIT_FAILURE);
  }
  printf("OK\n");

  /* -- Écoute sur la socket. ----------------------------------------------- */
  printf(" - Écoute sur la socket... ");
  fflush(stdout);
  if(listen(s, MAX_CONNECTIONS) == -1) {
    perror("Erreur lors de l'écoute sur la socket ");
    exit(EXIT_FAILURE);
  }
  printf("OK\n");

  /* -- Acceptation d'une demande de connexion. ----------------------------- */
  printf(" - Acceptation d'une demande de connexion... ");
  fflush(stdout);
  if((t = accept(s, &saCli, &saCliLen)) == -1) {
    perror("Erreur lors de l'acceptation de la connexion ");
    exit(EXIT_FAILURE);
  }
  printf("OK\n");

  /* -- Fermeture de la socket t. ---------------------------------------------- */
  printf(" - Fermeture de la socket client... ");
  fflush(stdout);
  if(close(t) == -1) {
    perror("Erreur à la fermeture de la socket client ");
    exit(EXIT_FAILURE);
  }
  printf("OK\n");

  /* -- Fermeture de la socket s. ---------------------------------------------- */
  printf(" - Fermeture de la socket serveur... ");
  fflush(stdout);
  if(close(s) == -1) {
    perror("Erreur à la fermeture de la socket serveur ");
    exit(EXIT_FAILURE);
  }
  printf("OK\n");

  return EXIT_SUCCESS;
} /* Fin du main(). */
